home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / djgpp / qdeck / sockets / tdaemon.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-11  |  5.2 KB  |  179 lines

  1. /*****************************************************************************
  2. *  
  3. *                                  DESQview/X 
  4. *                           BASIC TCP (STREAM) DAEMON
  5. *
  6. *  The following code demonstrates the implementation of a basic stream 
  7. *  daemon under DESQview/X.  Similar code may be used for daemons that are
  8. *  managed by the DESQview/X Network Manager, are activated in response to 
  9. *  a requested connection by a remote host, and process input as streams.
  10. *
  11. *  The basic methodology is as follows.  
  12. *
  13. *   - The DESQview/X Network Manager opens a 'listening' socket for the daemon
  14. *     based upon the contents of the NETWORK\INETD.CFG file, and the DVPs in 
  15. *     the NETWORK subdirectory.
  16. *
  17. *   - A connection is made to the socket, and the Network Manager 'accepts' 
  18. *     the connection.
  19. *
  20. *   - The Network Manager instructs DESQview/X to load the appropriate 
  21. *     DVP for the daemon (from INETD.CFG).
  22. *
  23. *   - The daemon is started and immediately requests information about the 
  24. *     new connection (the socket ID).
  25. *
  26. *   - The daemon processes the connection in whatever manner it sees fit, and
  27. *     closes the connection socket when finished.
  28. *
  29. *
  30. ******************************************************************************/
  31.  
  32.  
  33. #include <stdlib.h>
  34. #include <stdio.h>
  35. #include <string.h>
  36. #include <sys\time.h>
  37.  
  38. #include <netdb.h>        
  39. #include <netinet\in.h>    
  40. #include <sys\socket.h>
  41. #include <sys\errno.h>
  42. #include <sys\ioctl.h>
  43.  
  44.  
  45. void    chat(int s);
  46.  
  47. extern int kbhit(void);
  48.  
  49. void main(int argc, char *argv[])
  50. {
  51.     int    s;
  52.  
  53.     /* Daemon has been started by the Network Manager.  Request the connection */
  54.     /* information.  The second parameter to so_daemon indicates that we wish    */
  55.     /* to wait for the connection information.  If we wished to poll for the    */
  56.     /* next connection, we could simply specify FALSE in the second parameter.    */
  57.  
  58.     printf("\n\nDESQview/X Sample STREAM Daemon.");
  59.  
  60.     while(1){
  61.  
  62.         printf("\n\nRetrieving next connection.  Please wait.\n");
  63.  
  64.         s    =    so_daemon(argv,1);
  65.  
  66.         if(s < 0){
  67.             printf("\nError:  Unable to retrieve connection information.\n\n");
  68.             break;
  69.         }
  70.  
  71.         chat(s);
  72.  
  73.         so_close(s);
  74.  
  75.     }
  76. }
  77.  
  78.  
  79.  
  80. /*****************************************************************************
  81. *
  82. *    void    chat(int session);
  83. *
  84. *     The following code demonstrates some of the basic BSD4.3 socket I/O calls.
  85. *  Basically, we poll for data on the socket, while allowing the user to 
  86. *  enter some text which we then send to our connection partner.
  87. *
  88. ******************************************************************************/
  89. void    chat(int s)
  90. {
  91.     struct    timeval    t;                            /* set to 0 to indicate polling */
  92.     long        nonBlocking = 1l;                    
  93.     char        recvBuff[100];                        /* Buffer to receive data into */
  94.     char        sendBuff[100];                        /* Buffer data sent from */
  95.     unsigned long     ioBit,readBit,writeBit;            /* I/O bits for the socket */
  96.     int        bytes,i;                                
  97.     char        done;
  98.  
  99.     printf("\n\n-----------------------------------");
  100.     printf("---------------------------------------------\n");
  101.     printf("<Enter> - Send (blank line to end)\n\n");
  102.  
  103.     /*  Set the I/O strategy for the socket to non-blocking.  This will    */
  104.     /*  force I/O calls to return immediately if there is nothing to        */
  105.     /*     do.                                                                                    */
  106.        
  107.     ioctl(s,FIONBIO,(char *)&nonBlocking); 
  108.  
  109.     /*  Initialize the timeout for the select call to 0.  This will      */
  110.     /*  transform the call from a waiting call to a polling call.            */
  111.  
  112.     memset(&t,0,sizeof(struct timeval));
  113.  
  114.     /*  The select call takes pointers to bit arrays indicating which    */
  115.     /*  sockets we are concerned about.  Initialize the bit indicating   */
  116.     /*  the current socket.                                                                */
  117.  
  118.     ioBit = (long)(1l << s);
  119.  
  120.     done = 0;
  121.  
  122.     while(!done){
  123.  
  124.         writeBit = readBit = ioBit;    
  125.  
  126.         select(s + 1,(struct fd_set *)&readBit,(struct fd_set *)&writeBit,(struct fd_set *)NULL,&t);    /* Get read/write status */
  127.  
  128.         /* If the 'read' bit is still set after the select call, one of      */
  129.         /* two things is indicated.  Either the socket has been closed,     */
  130.         /* or there is data to read for the socket.                                 */
  131.  
  132.         if(readBit & ioBit){
  133.  
  134.             bytes = recv(s,recvBuff,sizeof(recvBuff),0);    
  135.  
  136.             switch(bytes){
  137.                 case 0:                                     /* Normal close    */
  138.                     printf("\n\nSession Terminated by Partner.\n\n");
  139.                     done = 1;
  140.                     break;
  141.                 case -1:                    
  142.                     if(errno != EWOULDBLOCK){        /* Abnormal close */
  143.                         printf("\n\nSession Terminated Abnormally on Read.\n\n");
  144.                         done = 1;
  145.                     }
  146.                     break;
  147.                 default:
  148.                     for(i = 0;i < bytes;i++)         /* Got some data    */
  149.                         printf("%c",recvBuff[i]);
  150.             }
  151.         } else {
  152.  
  153.         /* If the 'write' bit is set and a key has been hit, collect the    */
  154.         /* user data and send it to the connection partner.                    */
  155.  
  156.             if((writeBit & ioBit) && kbhit()){
  157.     
  158.                 strcpy(sendBuff,"<");
  159.                 gets(sendBuff + 1);
  160.  
  161.                 if(!strlen(sendBuff + 1)){
  162.                     done = 1;
  163.                     break;
  164.                 }
  165.                 strcat(sendBuff,">\n");
  166.     
  167.                 bytes = send(s,sendBuff,strlen(sendBuff),0);
  168.  
  169.                 if(bytes == -1 && errno != EWOULDBLOCK){        /* Error Occured */
  170.                     printf("\n\nSession Terminated Abnormally on Write.\n\n");
  171.                     done = 1;
  172.                 }
  173.             }
  174.         }        
  175.     }
  176. }
  177.  
  178.  
  179.